package com.example.binlog_connector_test.mysqllistener;


import com.github.shyiko.mysql.binlog.BinaryLogClient;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;


import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

@Component
public class ReportBinaryLogClient implements ApplicationContextAware {

    @Value("${spring.datasource.url}")
    private String url;
    @Value("${spring.datasource.username}")
    private String name;
    @Value("${spring.datasource.password}")
    private String password;
    @Autowired
    private ApplicationContext applicationContext;


    public BinaryLogClient buildBinaryLogClient() throws URISyntaxException, IOException {
        String dbName = ReportBinaryLogClient.findDataBaseNameByUrl(url);
        URI uri = new URI(url.substring(5)); // remove "jdbc:"
        String host = uri.getHost();
        int port = uri.getPort();
        BinaryLogClient binaryLogClient = new BinaryLogClient(host, port, dbName, name, password);
        binaryLogClient.registerEventListener(new DataChangeListener(applicationContext));
        binaryLogClient.connect();
        return binaryLogClient;
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        try {

            buildBinaryLogClient();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String findDataBaseNameByUrl(String jdbcUrl) {
        String database = null;
        int pos, pos1;
        String connUri;

        if (StringUtils.isBlank(jdbcUrl)) {
            throw new IllegalArgumentException("Invalid JDBC url.");
        }

        jdbcUrl = jdbcUrl.toLowerCase();

        if (jdbcUrl.startsWith("jdbc:impala")) {
            jdbcUrl = jdbcUrl.replace(":impala", "");
        }

        if (!jdbcUrl.startsWith("jdbc:")
                || (pos1 = jdbcUrl.indexOf(':', 5)) == -1) {
            throw new IllegalArgumentException("Invalid JDBC url.");
        }

        connUri = jdbcUrl.substring(pos1 + 1);

        if (connUri.startsWith("//")) {
            if ((pos = connUri.indexOf('/', 2)) != -1) {
                database = connUri.substring(pos + 1);
            }
        } else {
            database = connUri;
        }

        if (database.contains("?")) {
            database = database.substring(0, database.indexOf("?"));
        }

        if (database.contains(";")) {
            database = database.substring(0, database.indexOf(";"));
        }

        if (StringUtils.isBlank(database)) {
            throw new IllegalArgumentException("Invalid JDBC url.");
        }
        return database;
    }
}
